package com.qianli.cashmama.trade.repo.impl;

import com.fqgj.common.utils.CollectionUtils;
import com.fqgj.common.utils.TimeUtils;
import com.fqgj.exception.common.ApplicationException;
import com.qianli.cashmama.trade.common.enums.BillPaidStatusEnum;
import com.qianli.cashmama.trade.common.enums.BillStatusEnum;
import com.qianli.cashmama.trade.common.enums.TimeoutTypeEnum;
import com.qianli.cashmama.trade.common.utils.TradeConfigUtil;
import com.qianli.cashmama.trade.dao.TBillDao;
import com.qianli.cashmama.trade.dao.TTimeoutCenterDao;
import com.qianli.cashmama.trade.domain.model.BillBase;
import com.qianli.cashmama.trade.entity.TBillEntity;
import com.qianli.cashmama.trade.entity.TTimeoutCenterEntity;
import com.qianli.cashmama.trade.repo.BillBaseRepository;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Repository;

import java.util.ArrayList;
import java.util.Calendar;
import java.util.Date;
import java.util.List;

/**
 * Created with IntelliJ IDEA.
 * User: sm
 * Date: 2017/7/24
 * Time: 上午11:50
 */
@Repository
public class BillBaseRepositoryImpl implements BillBaseRepository {
    private static final Logger LOGGER = LoggerFactory.getLogger(BillBaseRepositoryImpl.class);

    @Autowired
    private TBillDao billDao;

    @Autowired
    private TTimeoutCenterDao tTimeoutCenterDao;

    @Autowired
    private TradeConfigUtil tradeConfigUtil;

    @Override
    public void storeList(List<BillBase> billList) {
        if (CollectionUtils.isEmpty(billList)) {
            return;
        }
        for (BillBase billBase : billList) {
            TBillEntity billEntity = billBaseToBillEntity(billBase);
//            billEntity.setId(IdCenterUtil.getSequenceNo(TradeBizCodeEnum.BILL));
            billEntity.setCreateDt(new Date());
            billDao.insert(billEntity);

            //超时中心相关逻辑
            try {
                pushToTimeoutCenter(billBase);
            } catch (Exception e) {
                LOGGER.error("== 超时中心生成的数据错误 ==,e", e);
            }

            if (billEntity.getId() == null) {
                throw new ApplicationException("An error occurred in the new bill");
            }
        }
    }


    @Override
    public BillBase getBillByBillNo(String billNo) {
        TBillEntity billEntity = billDao.selectOneByBillNo(billNo);
        return billEntityToBillBase(billEntity);
    }


    @Override
    public List<BillBase> getBillListByTradeNo(String tradeNo) {
        List<TBillEntity> billEntityList = billDao.selectListByTradeNo(tradeNo);
        if (CollectionUtils.isEmpty(billEntityList)) {
            return null;
        }
        List<BillBase> billBaseList = new ArrayList<>(billEntityList.size());
        for (TBillEntity billEntity : billEntityList) {
            billBaseList.add(billEntityToBillBase(billEntity));
        }

        return billBaseList;
    }


    @Override
    public void update(BillBase billBase) {
        TBillEntity entity = billDao.selectOneByBillNo(billBase.getBillNo());
        TBillEntity billEntity = billBaseToBillEntity(billBase);

        billEntity.setId(entity.getId());

        billDao.updateByPrimaryKey(billEntity);
    }

    private TBillEntity billBaseToBillEntity(BillBase billBase) {
        return new TBillEntity()
                .setBillNo(billBase.getBillNo())
                .setTradeNo(billBase.getTradeNo())
                .setBorrowCapital(billBase.getBorrowCapital())
                .setCurrentPeriod(billBase.getCurrentPeriod())

                .setDiscountCapital(billBase.getDiscountCapital())
                .setExtensionCount(billBase.getExtensionCount())
                .setOverdueFee(billBase.getOverdueFee())
                .setOverdueServiceFee(billBase.getOverdueServiceFee())
                .setTheoreticalTotalAmount(billBase.getTheoreticalTotalAmount())
                .setPaidCapital(billBase.getPaidCapital())

                .setRepaymentCapital(billBase.getRepaymentCapital())
                .setPaidStatus(billBase.getPaidStatus().getStatus())
                .setStatus(billBase.getStatus().getStatus())
                .setRepaymentDate(billBase.getRepaymentDate())

                .setReceivedCapital(billBase.getReceivedCapital())
                .setProductCategory(billBase.getProductCategory())
                .setProductCode(billBase.getProductCode())
                .setPayOffDate(billBase.getPayOffDate())
                .setInterestFee(billBase.getInterestFee())
                .setBorrowServiceFee(billBase.getBorrowServiceFee());
    }

    private BillBase billEntityToBillBase(TBillEntity billEntity) {
        if (billEntity == null) {
            return null;
        }

        return new BillBase()
                .setTradeNo(billEntity.getTradeNo())
                .setBillNo(billEntity.getBillNo())
                .setRepaymentCapital(billEntity.getRepaymentCapital())
                .setBorrowCapital(billEntity.getBorrowCapital())
                .setCurrentPeriod(billEntity.getCurrentPeriod())

                .setDiscountCapital(billEntity.getDiscountCapital())
                .setExtensionCount(billEntity.getExtensionCount())
                .setOverdueFee(billEntity.getOverdueFee())
                .setOverdueServiceFee(billEntity.getOverdueServiceFee())
                .setTheoreticalTotalAmount(billEntity.getTheoreticalTotalAmount())
                .setPaidCapital(billEntity.getPaidCapital())

                .setPaidStatus(BillPaidStatusEnum.concertByStatus(billEntity.getPaidStatus()))
                .setStatus(BillStatusEnum.conventByStatus(billEntity.getStatus()))
                .setPayOffDate(billEntity.getPayOffDate())
                .setRepaymentDate(billEntity.getRepaymentDate())

                .setReceivedCapital(billEntity.getReceivedCapital())
                .setProductCategory(billEntity.getProductCategory())
                .setProductCode(billEntity.getProductCode())
                .setInterestFee(billEntity.getInterestFee())
                .setBorrowServiceFee(billEntity.getBorrowServiceFee());
    }

    /**
     * @param billBase
     */
    public void pushToTimeoutCenter(BillBase billBase) {
        TTimeoutCenterEntity tTimeoutCenterEntity = new TTimeoutCenterEntity()
                .setType(TimeoutTypeEnum.OVERDUE.getType())
                .setTriggerTime(timeAppointed(TimeUtils.getDate(billBase.getRepaymentDate()), -2, 0))
                .setValue(billBase.getBillNo());

        tTimeoutCenterDao.insert(tTimeoutCenterEntity);

        TTimeoutCenterEntity tTimeoutCenterEntity1 = new TTimeoutCenterEntity()
                .setType(TimeoutTypeEnum.CHANGE_TO_OVERDUE_STATUS.getType())
                .setTriggerTime(timeAppointed(TimeUtils.getDate(billBase.getRepaymentDate()), 1, 0))
                .setValue(billBase.getBillNo());

        tTimeoutCenterDao.insert(tTimeoutCenterEntity1);

        for (int i = -1; i <= 0; i++) {
            TTimeoutCenterEntity pre10MessageEntity = new TTimeoutCenterEntity()
                    .setType(TimeoutTypeEnum.PRE_MESSAGE.getType())
                    .setTriggerTime(timeAppointed(billBase.getRepaymentDate(), i, 10))
                    .setValue(billBase.getBillNo());

            tTimeoutCenterDao.insert(pre10MessageEntity);

            if (i == 0) {
                TTimeoutCenterEntity pre18MessageEntity = new TTimeoutCenterEntity()
                        .setType(TimeoutTypeEnum.PRE_MESSAGE.getType())
                        .setTriggerTime(timeAppointed(billBase.getRepaymentDate(), i, 18))
                        .setValue(billBase.getBillNo());

                tTimeoutCenterDao.insert(pre18MessageEntity);

                TTimeoutCenterEntity pre14MessageEntity = new TTimeoutCenterEntity()
                        .setType(TimeoutTypeEnum.PRE_MESSAGE.getType())
                        .setTriggerTime(timeAppointed(billBase.getRepaymentDate(), i, 14))
                        .setValue(billBase.getBillNo());

                tTimeoutCenterDao.insert(pre14MessageEntity);
            }
        }

        TTimeoutCenterEntity entity = new TTimeoutCenterEntity()
                .setType(TimeoutTypeEnum.PRE_MESSAGE.getType())
                .setTriggerTime(timeAppointed(billBase.getRepaymentDate(), -3, 10))
                .setValue(billBase.getBillNo());
        tTimeoutCenterDao.insert(entity);

        // 逾期天数达到阈值 拉黑
//        TTimeoutCenterEntity blackEntity = new TTimeoutCenterEntity()
//                .setType(TimeoutTypeEnum.OVERDUE_BLACKLIST.getType())
//                .setTriggerTime(timeAppointed(billBase.getRepaymentDate(), tradeConfigUtil.overBlacklistThreshold(), 2))
//                .setValue(billBase.getTradeNo());
////        blackEntity.setId(IdCenterUtil.getSequenceNo(TradeBizCodeEnum.TIMEOUT_CENTER));
//        tTimeoutCenterDao.insert(blackEntity);
    }

    private static Date timeAppointed(Date date, int delta, int hour) {
        Calendar cal = Calendar.getInstance();
        cal.setTime(date);
        if (delta != 0) {
            cal.add(Calendar.DATE, delta);
        }
        cal.set(Calendar.HOUR_OF_DAY, hour);
        return cal.getTime();
    }

}
